// 引入子进程模块，用来执行其他命令或者软件
const Process = require("./ProcessTool.js");


// 定义Git工具对象
class GitTool {
    // 构造函数，传入一个环境地址
    constructor(cwd) {
        this.cwd = cwd;
    }
    // 生成一个指定目录环境的子进程对象
    childProcess(params){
        let child = new Process(this.cwd).asyncRun("git",params);
        return child;
    }
    // git branch
    async branch() {
        let gitMessage = await this.childProcess(["branch"]) || ""; // 有没有必要显示远程分支呢？ git branch -a
        let current = "";
        let branchs = gitMessage.split('\n').map(item => {
            let reg = new RegExp(/\*/g);
            if (reg.test(item)) {
                item = item.replace(reg, '');
                current = item.trim();
            }
            return item.trim();
        }).filter(item => item);

        return {
            current,
            branchs
        }
    }
    // git status
    status(params = ["status"]){
        // 如果没有变化，这里是不会返回内容的
        return this.childProcess(params);
    }
    // git pull origin branchName
    pull(branch){
        return this.childProcess(["pull","origin",branch]);
    }
    // git fetch origin master
    fetch(branch){
        return this.childProcess(["fetch"]);    // 不加分支名字是不是更好一点？这样可以直接更新整个仓库
    }
    // git add -A
    add(params = ["add","-A"]){
        // 如果没有变化，这里是不会返回内容的
        return this.childProcess(params);
    }
    // git commit -m 【remark]
    commit(remark){
        return this.childProcess(["commit","-m",remark]);
    }
    // git push origin branch
    push(branch){
        return this.childProcess(["push","origin",branch]);
    }
    // git checkout
    async checkout(branch) {
        // 这里切换分支会遇到很多钟情况，所以需要做下特殊处理。（比如构建了没有提交，文件未跟踪的时候无法切换分支）
        // 这里直接reset --hard origin branch 最新的一条记录
        await this.fetch(); // 先更新整个仓库
        let statusMessage = await this.status();
        // 判断是否存在变更
        if(statusMessage.indexOf("一致") == -1){   // 可能这样判断有点草率，看着有点捞。不过先这样吧。应该没啥问题
            if(statusMessage.indexOf("无文件要提交，干净的工作区") == -1){
                await this.add();   // 再把可能存在未添加到暂存区（没有git add ）的文件添加关联
                await this.commit("RJNode构建提交");    // 这里先随便提交一个commit，正常情况下是不会推送这个记录到远端的。
            }
        }
        // 本来是想判断当前分支是否是目标分支的，但是突然觉得，可以强制根据远程目标分支新开一个分支。这样好像可以省一些处理
        return this.childProcess(["checkout","-B",branch,`origin/${branch}`]);
    }

}

module.exports = GitTool;

